package QRCG;

import java.io.IOException;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class SignupServe
 */
@WebServlet("/SignupServe")
public class SignupServe extends HttpServlet {
	private static final long serialVersionUID = 1L;

  private static final int MAX_NICKNAME_LENGTH = 20;
  private static final int MAX_EMAIL_LENGTH = 80;
  private static final int MAX_NAME_LENGTH = 45;
  private static final int MAX_SURNAME_LENGTH = 15;

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		HttpSession session = request.getSession(true);

		String nickname = request.getParameter("nickname");
		String name = request.getParameter("name");
		String surname = request.getParameter("surname");
		String email = request.getParameter("email");
		String gender = request.getParameter("gender");
		if (gender == null) {
			// For not adding to the database, we use NULL keyword of SQL. Note
			// that there are no quotes.
			gender = "NULL";
		} else {
			gender = "\'" + gender + "\'";
		}
		String location = request.getParameter("location");
		String password1 = request.getParameter("password1");
		String password2 = request.getParameter("password2");

		String errorMessages = "";

		RequestDispatcher rd = request.getRequestDispatcher("SignUp.jsp");

		String namePattern = "[a-zA-Z]*";

    boolean success = true;
    if (!Util.hasTextContent(name)) {
      errorMessages += ("Name field cannot be empty! \n");
      success = false;
    }

    if (!Util.hasTextContent(nickname)) {
      errorMessages += ("Nickname field cannot be empty!  \n");
      success = false;
    }

    if (!Util.hasTextContent(surname)) {
      errorMessages += ("Surname field cannot be empty! \n");
      success = false;
    }

    if (!Util.hasTextContent(email)) {
      errorMessages += ("Email field cannot be empty! \n");
      success = false;
    }

    if (!Util.hasTextContent(password1) || !Util.hasTextContent(password2)) {
      errorMessages += ("Password fields cannot be empty! \n");
      success = false;
    }

		if (password1.compareTo(password2) != 0) {
		  errorMessages += ("Passwords are not the same! \n");
			success = false;
		}

		if (!Mailer.isValidMailAddress(email)) {
		  errorMessages += ("The provided mail address is invalid! \n");
			success = false;
		}

		if (!(nickname.matches(namePattern) && name.matches(namePattern) &&
		    surname.matches(namePattern))) {
			request.setAttribute("errorMessage",
					"Please use alphabetical characters in your nickname, name and surname! \n");
			success = false;
		}

    if (name.length() > MAX_NAME_LENGTH) {
      errorMessages += ("Name cannot be longer than " + MAX_NAME_LENGTH  + "characters! \n");
      success = false;
    }

    if (surname.length() > MAX_SURNAME_LENGTH) {
      errorMessages += ("Surname cannot be longer than " + MAX_SURNAME_LENGTH  + "characters! \n");
      success = false;
    }

    if (surname.length() > MAX_NICKNAME_LENGTH) {
      errorMessages += ("Nickname cannot be longer than " + MAX_NICKNAME_LENGTH  + "characters! \n");
      success = false;
    }

    if (surname.length() > MAX_EMAIL_LENGTH) {
      errorMessages += ("Email cannot be longer than " + MAX_EMAIL_LENGTH  + "characters! \n");
      success = false;
    }

		if (success) {
			DatabaseManager conn = new DatabaseManager();
			try {
				conn.connect();

				// checking if there is a user in the database with the given username or email
				if (conn.userExists(nickname, email)) {
				  errorMessages += ("Username/email already exists in the database, " +
				  		"please try another username/email!");
					success = false;
				} else {
					String hashPassword = Util.getMD5Hash(password1);

					String query = "INSERT INTO Users (name,surname, nickname,password,email,location_id,is_male)"
							+ "VALUES('"
							+ name
							+ "','"
							+ surname
							+ "','"
							+ nickname
							+ "','"
							+ hashPassword + "','" + email + "'," + location + "," + gender + ")";

					if (conn.execute(query)) {
						session.setAttribute("nickname", nickname);

						// creating cookies with username, password and email
						// information to be used by the forum.
						CookieManager.addSessionCookies(response, nickname, hashPassword, email);

						// also registering the user to the forum
						String forumQuery = "INSERT INTO jforum_users (username,user_password,user_email,user_regdate,gender)"
								+ "VALUES('"
								+ nickname
								+ "','"
								+ hashPassword
								+ "','"
								+ email
								+ "','"
								+ new Timestamp(System.currentTimeMillis())
								+ "',"
								+ gender
								+ ")";
						conn.execute(forumQuery);

						// putting user in to the user group "general" in the forum
						forumQuery = "INSERT INTO jforum_user_groups (group_id, user_id) VALUES(1, (SELECT MAX(u.user_id) FROM jforum_users u WHERE u.username='"
								+ nickname + "'))";
						conn.execute(forumQuery);

						response.sendRedirect("UserMainPage.jsp");
					} else {
					  errorMessages += ("Transaction could not be completed, please try again! \n");
						success = false;
					}
				}
			} catch (SQLException e) {
        errorMessages += ("Transaction could not be completed, please try again! \n");
        success = false;
			} finally {
				if(success){
					session.setAttribute("user_id", conn.getUserInformation(DatabaseManager.UserInformation.ID, nickname));
				}
			  conn.close();
			}
		}

		// If there is an error, return back to the SignUp.jsp and keep the
		// values the user entered.
		if (!success) {
		  request.setAttribute("errorMessages", errorMessages);
			request.setAttribute("nickname", nickname);
			request.setAttribute("name", name);
			request.setAttribute("surname", surname);
			request.setAttribute("email", email);
			request.setAttribute("gender", gender.compareTo("NULL") == 0 ? null : gender);
			request.setAttribute("location", location);
			rd.forward(request, response);
			return;
		}
	}
}
